<?php
/**
 * [LupMisNotAllowedSync]
 * 本代码为系统自动生成代码，请根据自己业务进行修改;
 * 生成时间 2022-02-01 22:12:12;
 * 版权所有 2020-2022 lizhongwen，并保留所有权利;
 * 说明: 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用；不允许对程序代码以任何形式任何目的的再发布;
 * 作者: 中文Lee;
 * 作者主页: http://www.lizhongwen.com;
 * 邮箱: 360811363@qq.com;
 * QQ: 360811363;
 */

namespace application\core;

use Redis;

class RedisUtil
{

    private static $obj;

    private static $redis;

    public static function instance(): RedisUtil
    {
        if (!isset(self::$obj) || is_null(self::$obj)) {
            $conf = json_decode(REDIS, JSON_UNESCAPED_UNICODE);
            self::$redis = new Redis();
            self::$redis->connect($conf['host'], $conf['port']);
            if (self::$redis->auth($conf['password']) == false) {
                die("password:" . self::$redis->getLastError());
            }
            self::$redis->select($conf['dbIndex']);
            self::$obj = new self();
        }
        return self::$obj;
    }

    /**
     * 得到一个key
     *
     * @param $str
     * @return array
     */
    public function keys($str): array
    {
        return self::$redis->keys($str);
    }

    /**
     * 设置一个key
     *
     * @param  $key
     * @param  $value
     * @return bool
     */
    public function set($key, $value): bool
    {
        return self::$redis->set($key, $value);
    }

    /**
     * 得到一个key
     *
     * @param $key
     * @return false|mixed|string
     */
    public function get($key)
    {
        return self::$redis->get($key);
    }

    /**
     * 设置一个有过期时间的key
     *
     * @param $key
     * @param  $expire
     * @param $value
     * @return bool
     */
    public function setex($key, $expire, $value): bool
    {
        return self::$redis->setex($key, $expire, $value);
    }

    /**
     * 设置一个key,如果key存在,不做任何操作.
     * @param $key
     * @param $value
     * @return bool
     */
    public function setnx($key, $value): bool
    {
        return self::$redis->setnx($key, $value);
    }

    /**
     * 批量设置key
     * @param $arr
     * @return bool
     */
    public function mset($arr): bool
    {
        return self::$redis->mset($arr);
    }

    /**
     * 得到hash表中一个字段的值
     * @param $key
     * @param $field
     * @return false|string
     */
    public function hGet($key, $field)
    {
        return self::$redis->hGet($key, $field);
    }

    /**
     * hash表设定一个字段的值
     * @param $key
     * @param $field
     * @param $value
     * @return bool|int
     */
    public function hSet($key, $field, $value)
    {
        return self::$redis->hSet($key, $field, $value);
    }

    /**
     * 判断hash表中，指定field是不是存在
     * @param $key
     * @param $field
     * @return bool
     */
    public function hExists($key, $field): bool
    {
        return self::$redis->hExists($key, $field);
    }

    /**
     * 删除hash表中指定字段 ,支持批量删除
     * @param string $key
     * @param string $field
     * @return int
     */
    public function hDel(string $key, string $field): int
    {
        $fieldArr = explode(',', $field);
        $delNum = 0;

        foreach ($fieldArr as $row) {
            $row = trim($row);
            $delNum += self::$redis->hDel($key, $row);
        }

        return $delNum;
    }

    /**
     * 返回hash表元素个数
     * @param $key
     * @return false|int
     */
    public function hLen($key)
    {
        return self::$redis->hLen($key);
    }

    /**
     * 为hash表设定一个字段的值,如果字段存在，返回false
     * @param $key
     * @param $field
     * @param $value
     * @return bool
     */
    public function hSetNx($key, $field, $value): bool
    {
        return self::$redis->hSetNx($key, $field, $value);
    }

    /**
     * 为hash表多个字段设定值。
     * @param $key
     * @param $value
     * @return bool
     */
    public function hMset($key, $value): bool
    {
        if (!is_array($value))
            return false;
        return self::$redis->hMset($key, $value);
    }

    /**
     * 为hash表多个字段设定值。
     * @param string $key
     * @param string $field 以,号分隔字段
     * @return array
     */
    public function hMget(string $key, string $field): array
    {
        if (!is_array($field))
            $field = explode(',', $field);
        return self::$redis->hMget($key, $field);
    }

    /**
     * 为hash表设这累加，可以负数
     * @param $key
     * @param $field
     * @param $value
     * @return int
     */
    public function hIncrBy($key, $field, $value): int
    {
        $value = intval($value);
        return self::$redis->hIncrBy($key, $field, $value);
    }

    /**
     * 返回所有hash表的所有字段
     * @param $key
     * @return array
     */
    public function hKeys($key): array
    {
        return self::$redis->hKeys($key);
    }

    /**
     * 返回所有hash表的字段值，为一个索引数组
     * @param $key
     * @return array
     */
    public function hVals($key): array
    {
        return self::$redis->hVals($key);
    }

    /**
     * 返回所有hash表的字段值，为一个关联数组
     * @param $key
     * @return array
     */
    public function hGetAll($key): array
    {
        return self::$redis->hGetAll($key);
    }

    /**
     * *******************有序集合操作********************
     */

    /**
     * 给当前集合添加一个元素
     * 如果value已经存在，会更新order的值。
     * @param $key
     * @param $order
     * @param $value
     * @return int
     */
    public function zAdd($key, $order, $value): int
    {
        return self::$redis->zAdd($key, $order, $value);
    }


    /**
     * 删除值为value的元素
     * @param $key
     * @param $value
     * @return int
     */
    public function zRem($key, $value): int
    {
        return self::$redis->zRem($key, $value);
    }

    /**
     * 集合以order递增排列后，0表示第一个元素，-1表示最后一个元素
     * @param $key
     * @param $start
     * @param $end
     * @return array
     */
    public function zRange($key, $start, $end): array
    {
        return self::$redis->zRange($key, $start, $end);
    }

    /**
     * 集合以order递减排列后，0表示第一个元素，-1表示最后一个元素
     * @param $key
     * @param $start
     * @param $end
     * @return array
     */
    public function zRevRange($key, $start, $end): array
    {
        return self::$redis->zRevRange($key, $start, $end);
    }

    /**
     *  * 集合以order递增排列后，返回指定order之间的元素。
     * min和max可以是-inf和+inf 表示最大值，最小值
     * @param string $key
     * @param string $start
     * @param string $end
     * @param array $option
     * @return array
     */
    public function zRangeByScore(string $key, string $start = '-inf', string $end = "+inf", array $option = []): array
    {
        return self::$redis->zRangeByScore($key, $start, $end, $option);
    }

    /**
     * @param string $key
     * @param string $start
     * @param string $end
     * @param array $option
     * @return array
     */
    public function zRevRangeByScore(string $key, string $start = '-inf', string $end = "+inf", array $option = []): array
    {
        return self::$redis->zRevRangeByScore($key, $start, $end, $option);
    }

    /**
     * 返回order值在start end之间的数量
     * @param $key
     * @param $start
     * @param $end
     * @return int
     */
    public function zCount($key, $start, $end): int
    {
        return self::$redis->zCount($key, $start, $end);
    }

    /**
     * 返回值为value的order值
     * @param $key
     * @param $value
     * @return bool|float
     */
    public function zScore($key, $value)
    {
        return self::$redis->zScore($key, $value);
    }

    /**
     * 返回集合以score递增加排序后，指定成员的排序号，从0开始。
     * @param $key
     * @param $value
     * @return false|int
     */
    public function zRank($key, $value)
    {
        return self::$redis->zRank($key, $value);
    }

    /**
     * 返回集合以score递增加排序后，指定成员的排序号，从0开始。
     * @param $key
     * @param $value
     * @return false|int
     */
    public function zRevRank($key, $value)
    {
        return self::$redis->zRevRank($key, $value);
    }

    /**
     * 删除集合中，score值在start end之间的元素 包括start end
     * min和max可以是-inf和+inf 表示最大值，最小值
     * @param $key
     * @param $start
     * @param $end
     * @return int
     */
    public function zRemRangeByScore($key, $start, $end): int
    {
        return self::$redis->zRemRangeByScore($key, $start, $end);
    }

    /**
     * 返回集合元素个数。
     * @param $key
     * @return int
     */
    public function zCard($key): int
    {
        return self::$redis->zCard($key);
    }

    /**
     * *******************队列操作命令***********************
     */

    /**
     * 在队列尾部插入一个元素
     * @param $key
     * @param $value
     * @return false|int
     */
    public function rPush($key, $value)
    {
        return self::$redis->rPush($key, $value);
    }

    /**
     * 在队列尾部插入一个元素 如果key不存在，什么也不做
     * @param $key
     * @param $value
     * @return false|int
     */
    public function rPushx($key, $value)
    {
        return self::$redis->rPushx($key, $value);
    }

    /**
     * 在队列头部插入一个元素
     * @param $key
     * @param $value
     * @return false|int
     */
    public function lPush($key, $value)
    {
        return self::$redis->lPush($key, $value);
    }

    /**
     * 在队列头插入一个元素 如果key不存在，什么也不做
     * @param $key
     * @param $value
     * @return false|int
     */
    public function lPushx($key, $value)
    {
        return self::$redis->lPushx($key, $value);
    }

    /**
     * 返回队列长度
     * @param $key
     * @return bool|int
     */
    public function lLen($key)
    {
        return self::$redis->lLen($key);
    }

    /**
     * 返回队列指定区间的元素
     * @param $key
     * @param $start
     * @param $end
     * @return array
     */
    public function lRange($key, $start, $end): array
    {
        return self::$redis->lrange($key, $start, $end);
    }

    /**
     * 返回队列中指定索引的元素
     * @param $key
     * @param $index
     * @return bool|mixed
     */
    public function lIndex($key, $index)
    {
        return self::$redis->lIndex($key, $index);
    }

    /**
     * 设定队列中指定index的值。
     * @param $key
     * @param $index
     * @param $value
     * @return bool
     */
    public function lSet($key, $index, $value): bool
    {
        return self::$redis->lSet($key, $index, $value);
    }

    /**
     * 删除值为value的count个元素
     * PHP-REDIS扩展的数据顺序与命令的顺序不太一样，不知道是不是bug
     * count>0 从尾部开始
     * >0 从头部开始
     * =0 删除全部
     * @param $key
     * @param $count
     * @param $value
     * @return bool|int
     */
    public function lRem($key, $count, $value)
    {
        return self::$redis->lRem($key, $value, $count);
    }

    /**
     * 删除并返回队列中的头元素。
     * @param $key
     * @return bool|mixed
     */
    public function lPop($key)
    {
        return self::$redis->lPop($key);
    }

    /**
     * 删除并返回队列中的尾元素
     * @param $key
     * @return bool|mixed
     */
    public function rPop($key)
    {
        return self::$redis->rPop($key);
    }

    /**
     * 删除指定的key
     * @param $key1
     * @return int
     */
    public function del($key1): int
    {
        return self::$redis->del($key1, null, null);
    }

    /**
     * 增加元素到无序集合中
     * @param $key
     * @param $member
     * @return false|mixed
     */
    public function sadd($key, $member)
    {
        if (is_array($member)) {
            $params = $member;
        } else {
            $params[] = $member;
        }

        array_unshift($params, $key);
        return call_user_func_array([
            self::$redis,
            'sadd'
        ], $params);
    }

    /**
     * 集合内元素的总数
     * @param $key
     * @return int
     */
    public function scard($key): int
    {
        return self::$redis->scard($key);
    }

    public function sismember($key, $member): bool
    {
        return self::$redis->sismember($key, $member);
    }

    /**
     * 清空集合
     * @param $key
     * @return false|mixed
     */
    public function clearSet($key)
    {
        $set = $this->smembers($key);
        return $this->srem($key, $set);
    }

    /**
     * 集合内元素列表
     * @param $key
     * @return array
     */
    public function smembers($key): array
    {
        return self::$redis->smembers($key);
    }

    /**
     * 删除集合元素
     * @param $key
     * @param $member
     * @return false|mixed
     */
    public function srem($key, $member)
    {
        if (is_array($member)) {
            $params = $member;
        } else {
            $params[] = $member;
        }

        array_unshift($params, $key);
        return call_user_func_array([
            self::$redis,
            'srem'
        ], $params);
    }
}